/*
    Licensed to the Apache Software Foundation (ASF) under one
    or more contributor license agreements.  See the NOTICE file
    distributed with this work for additional information
    regarding copyright ownership.  The ASF licenses this file
    to you under the Apache License, Version 2.0 (the
    "License"); you may not use this file except in compliance
    with the License.  You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing,
    software distributed under the License is distributed on an
    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    KIND, either express or implied.  See the License for the
    specific language governing permissions and limitations
    under the License.
 */
package erwiki.ui.app.handlers;

import java.security.Principal;
import java.util.ResourceBundle;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;
import org.eclipse.e4.core.di.annotations.Execute;
import org.eclipse.e4.ui.services.IServiceConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.window.Window;
import org.eclipse.rap.rwt.RWT;
import org.eclipse.swt.widgets.Shell;

import erwiki.api.auth.AuthenticationManager;
import erwiki.api.authorization.login.CookieAssertionLoginModule;
import erwiki.api.authorization.login.CookieAuthenticationLoginModule;
import erwiki.api.core.Engine;
import erwiki.api.core.WikiSession;
import erwiki.api.exceptions.WikiSecurityException;
import erwiki.api.preferences.Preferences;
import erwiki.api.rwc.RWC;
import erwiki.ui.app.dialogs.LoginDialog;
import jakarta.inject.Inject;
import jakarta.inject.Named;

public class LoginHandler {

	private static final Logger log = Logger.getLogger(LoginHandler.class);

	@Inject
	Engine engine;

	@Execute
	public void execute(@Named(IServiceConstants.ACTIVE_SHELL) Shell shell) {
		LoginDialog loginDialog = new LoginDialog(shell);
		if (loginDialog.open() == Window.OK) {
			try {
				// :FVK: TODO: login ...
				logging(loginDialog.getUserName(), loginDialog.getPassword());
			} catch (WikiSecurityException e) {
				MessageDialog.openError(shell, "Error", "Error login: " + e.getMessage());
			}
		}
	}

	protected void logging(String userName, String password) throws WikiSecurityException {
		AuthenticationManager mgr = engine.getManager(AuthenticationManager.class);
		WikiSession wikiSession = RWC.INSTANCE.getWikiSession();
		HttpServletRequest httpRequest = RWC.INSTANCE.getHttpRequest();

		// Если НЕ используется аутентификация контейнера, выполните всю логику управления доступом здесь...
		// (Примечание: если используется аутентификация контейнера, то он выполнит все это за нас.)
		if (!mgr.isContainerAuthenticated()) {
			// Если пользователь попал сюда и уже прошел аутентификацию, это означает, что ему просто не
			// разрешен доступ к тому, что он запросил. Плаксивые слезы и платочки повсюду.
			if (wikiSession.isAuthenticated()) {
				// TODO: OLD CODE: httpResponse.sendError(HttpServletResponse.SC_FORBIDDEN,
				// rb.getString("login.error.noaccess"));
				return;
			}
			log.debug("Attempting to authenticate user " + userName + "/" + password);

			// Авторизировать пользователя!
			if (mgr.loginAsserted(wikiSession, httpRequest, userName, password)) {
				log.info("Successfully authenticated user " + userName + " (custom auth)");
			} else {
				log.info("Failed to authenticate user " + userName);
				ResourceBundle rb = Preferences.getBundle();
				wikiSession.addMessage("login", rb.getString("login.error.password")); // TODO: выдать ошибку
																						// имени|пароля.
			}
		} else {
			// Использование контейнера для аутентификации. (:FVK: - проверить, портировать функциональность...)
			HttpSession httpSession = httpRequest.getSession();

			//
			// Нас уже представили?
			// Если да, то мы можем предположить, что уже входили в систему ранее.
			//
			Object seen = httpSession.getAttribute("_redirect");
			if (seen != null) {
				// TODO: OLD CODE: httpResponse.sendError(HttpServletResponse.SC_FORBIDDEN,
				// rb.getString("login.error.noaccess"));
				httpSession.removeAttribute("_redirect");
				return;
			}
			httpSession.setAttribute("_redirect", "I love Outi"); // Just any marker will do

			// Если используется аутентификация контейнера, то контейнер автоматически попытается
			// зарегистрировать пользователя.
			// Таким образом, если мы попали сюда, контейнер уже должен был аутентифицировать пользователя.
			// Все, что мы делаем, это просто фиксируем этот факт.

			Principal user = wikiSession.getLoginPrincipal();
			log.info("Successfully authenticated user " + user.getName() + " (container auth)");
		}

		// Если пользователь вошел в систему, то установить файл cookie пользователя с именем
		// user-принципала.
		if (wikiSession.isAuthenticated()) {
			HttpServletResponse httpResponse = RWT.getResponse();

			// Установить cookie файл пользователя.
			Principal principal = wikiSession.getUserPrincipal();
			CookieAssertionLoginModule.setUserCookie(httpResponse, principal.getName());

			// :FVK: String remember = httpRequest.getParameter("j_remember");
			// :FVK: if (remember != null)
			{
				CookieAuthenticationLoginModule.setLoginCookie(engine, httpResponse, principal.getName());
			}
		}
	}

}
